package com.zuipin.util;

import java.io.UnsupportedEncodingException;
import java.text.ParseException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import com.zuipin.enums.SerialNumberEnum;

/**
 * @author
 */

@Component
public class RedisUtils {
	
	public static String	order_serial_number	= "order_serial_number";
	private static String	redisCode			= "utf-8";
	@Autowired
	private RedisTemplate	redisTemplate;
	
	public RedisTemplate getRedisTemplate() {
		return redisTemplate;
	}
	
	public void setRedisTemplate(RedisTemplate redisTemplate) {
		this.redisTemplate = redisTemplate;
	}
	
	/**
	 * @Description:流水号补0
	 * @Title:
	 * @author: xujinding
	 * @date: 2017年3月28日下午7:40:25
	 */
	
	public static String buildSerialNumber(Long seqNo, Integer size) {
		String seqStr = String.valueOf(seqNo);
		StringBuffer sb = new StringBuffer();
		if (seqStr.length() < size) {
			Integer len = size - seqStr.length();
			for (int i = 0; i < len; i++) {
				sb.append("0");
			}
		}
		sb.append(seqStr);
		return sb.toString();
	}
	
	/**
	 * 获取流水号 type 类型
	 * 
	 * @Description:
	 * @Title:
	 * @author: xujinding
	 * @throws ParseException
	 * @date: 2017年3月28日下午7:03:05
	 */
	public String getSerialNumber(SerialNumberEnum type) throws ParseException {
		String key = type.getValue() + DateUtils.getDateNo();
		RedisConnection conn = redisTemplate.getConnectionFactory().getConnection();
		String res = key + buildSerialNumber(conn.incr(key.getBytes()), type.getsize());
		conn.pExpireAt(key.getBytes(), System.currentTimeMillis() + 60 * 60 * 24 * 1000);
		return res;
	}
	
	/**
	 * 获取品牌ID自增长
	 *
	 * @Title: getBrandNumber 
	 * @author: wuyicheng
	 * @date: 2017年8月15日下午2:59:29 
	 * @param type
	 * @return
	 * @throws ParseException
	 * @return: String
	 * @throws
	 */
	public String getNumber(SerialNumberEnum type) throws ParseException {
		RedisConnection conn = redisTemplate.getConnectionFactory().getConnection();
		String key = buildSerialNumber(conn.incr(type.getValue().getBytes()), type.getsize());
		return key;
	}
	
	/**
	 * @param key
	 */
	
	public long del(final String... keys) {
		
		return (Long) redisTemplate.execute(new RedisCallback() {
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				long result = 0;
				for (int i = 0; i < keys.length; i++) {
					result = connection.del(keys[i].getBytes());
				}
				return result;
			}
		});
	}
	
	/**
	 * @param key
	 * @param value
	 * @param liveTime
	 */
	
	public void set(final byte[] key, final byte[] value, final long liveTime) {
		redisTemplate.execute(new RedisCallback() {
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				connection.set(key, value);
				if (liveTime > 0) {
					connection.expire(key, liveTime);
				}
				return 1L;
			}
		});
	}
	
	/**
	 * @param key
	 * @param value
	 * @param liveTime
	 */
	
	public void set(String key, String value, long liveTime) {
		this.set(key.getBytes(), value.getBytes(), liveTime);
	}
	
	/**
	 * @param key
	 * @param value
	 */
	
	public void set(String key, String value) {
		this.set(key, value, 0L);
	}
	
	/**
	 * @param key
	 * @param value
	 */
	
	public void set(byte[] key, byte[] value) {
		this.set(key, value, 0L);
	}
	
	/**
	 * @param key
	 * @return
	 */
	
	public String get(final String key) {
		return (String) redisTemplate.execute(new RedisCallback() {
			public String doInRedis(RedisConnection connection) throws DataAccessException {
				try {
					return new String(connection.get(key.getBytes()), redisCode);
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
				return "";
			}
		});
	}
	
	/**
	 * @param key
	 * @return
	 */
	
	public boolean exists(final String key) {
		return (Boolean) redisTemplate.execute(new RedisCallback() {
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.exists(key.getBytes());
			}
		});
	}
	
	/**
	 * @return
	 */
	
	public String flushDB() {
		return (String) redisTemplate.execute(new RedisCallback() {
			public String doInRedis(RedisConnection connection) throws DataAccessException {
				connection.flushDb();
				return "ok";
			}
		});
	}
	
	/**
	 * @return
	 */
	
	public long dbSize() {
		return (Long) redisTemplate.execute(new RedisCallback() {
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.dbSize();
			}
		});
	}
	
	/**
	 * @return
	 */
	
	public String ping() {
		return (String) redisTemplate.execute(new RedisCallback() {
			public String doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.ping();
			}
		});
	}
}
